<template>
	<div :style="{ height: height + 'px', zIndex: zIndex }">
		<div
			:class="className"
			:style="{
				top: isSticky ? stickyTop + 'px' : '',
				zIndex: zIndex,
				position: position,
				width: width,
				height: height + 'px'
			}"
		>
			<slot>
				<div>sticky</div>
			</slot>
		</div>
	</div>
</template>

<script>
	export default {
		name: 'Sticky',
		props: {
			stickyTop: {
				type: Number,
				default: 0
			},
			zIndex: {
				type: Number,
				default: 1
			},
			className: {
				type: String,
				default: ''
			}
		},
		data() {
			return {
				active: false,
				position: '',
				width: undefined,
				height: undefined,
				isSticky: false
			};
		},
		mounted() {
			this.height = this.$el.getBoundingClientRect().height;
			window.addEventListener('scroll', this.handleScroll);
			window.addEventListener('resize', this.handleResize);
		},
		activated() {
			this.handleScroll();
		},
		destroyed() {
			window.removeEventListener('scroll', this.handleScroll);
			window.removeEventListener('resize', this.handleResize);
		},
		methods: {
			sticky() {
				if (this.active) {
					return;
				}
				this.position = 'fixed';
				this.active = true;
				this.width = this.width + 'px';
				this.isSticky = true;
			},
			handleReset() {
				if (!this.active) {
					return;
				}
				this.reset();
			},
			reset() {
				this.position = '';
				this.width = 'auto';
				this.active = false;
				this.isSticky = false;
			},
			handleScroll() {
				const width = this.$el.getBoundingClientRect().width;
				this.width = width || 'auto';
				const offsetTop = this.$el.getBoundingClientRect().top;
				if (offsetTop < this.stickyTop) {
					this.sticky();
					return;
				}
				this.handleReset();
			},
			handleResize() {
				if (this.isSticky) {
					this.width = this.$el.getBoundingClientRect().width + 'px';
				}
			}
		}
	};
</script>
